/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Engine2D.entity;

import java.util.ArrayList;
import Engine2D.Game;
import Engine2D.entity.Entity;
import Engine2D.graphics.GLColour;
import Engine2D.graphics.GLSpriteSheet;
import Engine2D.graphics.particle.GLParticleSystem;
import Engine2D.graphics.animation.Animation;
import Engine2D.level.Level;
import Engine2D.level.tile.Tile;
import Engine2D.level.tile.TileManager;
import Engine2D.graphics.animation.Frame;
import Engine2D.graphics.GLImage;
import Engine2D.input.InputHandler;
import org.lwjgl.input.Keyboard;

/**
 *
 * @author gary.morris
 */
public class Player extends Entity {

    private final InputHandler input;
    private final Game game;
    private char moveDir;
    private int moveTime;
    /**
     * 
     */
    protected int walkDist = 0;
    private ArrayList<Animation> animations = new ArrayList<Animation>();
    private Animation currentAnim;
    private int animCounter;
    private char dir;
    /**
     * 
     */
    public int blocksSmashed = 0;
    /**
     * 
     */
    public int gemsCollected = 0;
    private GLSpriteSheet image = null;
    private boolean stopped = false;
    public String name;

    /**
     * 
     * @param game
     * @param input
     */
    public Player(Game game, InputHandler input, String name) {
        this.input = input;
        this.game = game;
        this.name = name;
        x = 48;
        y = 48;
        image = GLSpriteSheet.getInstance();
    }

    /**
     * 
     * @param ticks
     */
    public void tick(int ticks) {
        super.tick(ticks);

        int xa = 0;
        int ya = 0;

        if (!stopped) {
            if (isSwimming()) {
                level.addParticleSystem(new GLParticleSystem(x + 14, y + 16, 1, 5000l, 1000l, 0f, -0.5f, 0f, GLColour.WHITE, "water"));
                if (input.isKeyDown(Keyboard.KEY_UP)) {
                    currentAnim = animations.get(8);
                    if (!currentAnim.getAnimationRunning()) {
                        currentAnim.reset();
                    }
                    ya -= 2;
                }
                if (input.isKeyDown(Keyboard.KEY_DOWN)) {
                    currentAnim = animations.get(7);
                    if (!currentAnim.getAnimationRunning()) {
                        currentAnim.reset();
                    }
                    ya += 2;
                }
                if (input.isKeyDown(Keyboard.KEY_LEFT)) {
                    currentAnim = animations.get(5);
                    if (!currentAnim.getAnimationRunning()) {
                        currentAnim.reset();
                    }
                    xa -= 2;
                }
                if (input.isKeyDown(Keyboard.KEY_RIGHT)) {
                    currentAnim = animations.get(6);
                    if (!currentAnim.getAnimationRunning()) {
                        currentAnim.reset();
                    }
                    xa += 2;
                }

            } else {


                if (input.isKeyDown(Keyboard.KEY_SPACE)) {
                    currentAnim = animations.get(0);
                    if (!currentAnim.getAnimationRunning()) {
                        currentAnim.reset();
                    }
                    attack();
                }

                if (input.isKeyDown(Keyboard.KEY_UP)) {
                    currentAnim = animations.get(4);

                    if (!currentAnim.getAnimationRunning()) {
                        currentAnim.reset();
                    }
                    if (input.isKeyDown(Keyboard.KEY_R)) {
                        ya -= 10;
                    } else {
                        ya -= 2;
                    }
                }
                if (input.isKeyDown(Keyboard.KEY_DOWN)) {
                    currentAnim = animations.get(3);
                    if (!currentAnim.getAnimationRunning()) {
                        currentAnim.reset();
                    }
                    if (input.isKeyDown(Keyboard.KEY_R)) {
                        ya += 10;
                    } else {
                        ya += 2;
                    }
                }
                if (input.isKeyDown(Keyboard.KEY_LEFT)) {
                    currentAnim = animations.get(1);
                    if (!currentAnim.getAnimationRunning()) {
                        currentAnim.reset();
                    }
                    if (input.isKeyDown(Keyboard.KEY_R)) {
                        xa -= 10;
                    } else {
                        xa -= 2;
                    }
                }
                if (input.isKeyDown(Keyboard.KEY_RIGHT)) {
                    currentAnim = animations.get(2);
                    if (!currentAnim.getAnimationRunning()) {
                        currentAnim.reset();
                    }
                    if (input.isKeyDown(Keyboard.KEY_R)) {
                        xa += 10;
                    } else {
                        xa += 2;
                    }
                }
            }


            if (input.isKeyPressed(Keyboard.KEY_P)) {
                place();
            }
        }
    
    

    
        else {
            currentAnim.stop();
    }
    
    if (xa 
    != 0 || ya 

    
        != 0) {
            if (xa < 0) {
            dir = 'l';
        }
        if (xa > 0) {
            dir = 'r';
        }
        if (ya < 0) {
            dir = 'u';
        }
        if (ya > 0) {
            dir = 'd';
        }

        move(xa, ya);
    }

    currentAnim.tick (ticks);
}
/**
 * 
 * @param level
 */
public void init(Level level) {

        this.level = level;

        Animation attack = new Animation();
        attack.addFrame(new Frame(GLSpriteSheet.getInstance(), 64, 32, 96f, 192f, 32, 0));
        attack.addFrame(new Frame(GLSpriteSheet.getInstance(), 32, 32, 160f, 192f, 0, 0));
        attack.addFrame(new Frame(GLSpriteSheet.getInstance(), 32, 32, 192f, 192f, 0, 0));
        attack.addFrame(new Frame(GLSpriteSheet.getInstance(), 64, 32, 224f, 192f, 32, 0));
        attack.addFrame(new Frame(GLSpriteSheet.getInstance(), 64, 32, 288f, 192f, 32, 0));
        attack.setAnimationUpdateInterval(150);
        attack.setAnimationLoop(false);
        animations.add(attack);


        Animation walkL = new Animation();
        walkL.addFrame(new Frame(GLSpriteSheet.getInstance(), 32, 32, 0f, 288f, 0, 0));
        walkL.addFrame(new Frame(GLSpriteSheet.getInstance(), 32, 32, 32f, 288f, 0, 0));
        walkL.addFrame(new Frame(GLSpriteSheet.getInstance(), 32, 32, 64f, 288f, 0, 0));
        walkL.setAnimationUpdateInterval(150);
        walkL.setAnimationLoop(false);
        animations.add(walkL);

        Animation walkR = new Animation();
        walkR.addFrame(new Frame(GLSpriteSheet.getInstance(), 32, 32, 0f, 256f, 0, 0));
        walkR.addFrame(new Frame(GLSpriteSheet.getInstance(), 32, 32, 32f, 256f, 0, 0));
        walkR.addFrame(new Frame(GLSpriteSheet.getInstance(), 32, 32, 64f, 256f, 0, 0));
        walkR.setAnimationUpdateInterval(150);
        walkR.setAnimationLoop(false);
        animations.add(walkR);

        Animation walkD = new Animation();
        walkD.addFrame(new Frame(GLSpriteSheet.getInstance(), 32, 32, 0f, 320f, 0, 0));
        walkD.addFrame(new Frame(GLSpriteSheet.getInstance(), 32, 32, 32f, 320f, 0, 0));
        walkD.addFrame(new Frame(GLSpriteSheet.getInstance(), 32, 32, 64f, 320f, 0, 0));
        walkD.setAnimationUpdateInterval(150);
        walkD.setAnimationLoop(false);
        animations.add(walkD);

        Animation walkU = new Animation();
        walkU.addFrame(new Frame(GLSpriteSheet.getInstance(), 32, 32, 0f, 224f, 0, 0));
        walkU.addFrame(new Frame(GLSpriteSheet.getInstance(), 32, 32, 32f, 224f, 0, 0));
        walkU.addFrame(new Frame(GLSpriteSheet.getInstance(), 32, 32, 64f, 224f, 0, 0));
        walkU.setAnimationUpdateInterval(150);
        walkU.setAnimationLoop(false);
        animations.add(walkU);


        Animation swimL = new Animation();
        swimL.addFrame(new Frame(GLSpriteSheet.getInstance(), 32, 32, 288f, 224f, 0, 0));
        swimL.addFrame(new Frame(GLSpriteSheet.getInstance(), 32, 32, 320f, 224f, 0, 0));
        swimL.setAnimationUpdateInterval(200);
        swimL.setAnimationLoop(false);
        animations.add(swimL);

        Animation swimR = new Animation();
        swimR.addFrame(new Frame(GLSpriteSheet.getInstance(), 32, 32, 224f, 224f, 0, 0));
        swimR.addFrame(new Frame(GLSpriteSheet.getInstance(), 32, 32, 256, 224f, 0, 0));
        swimR.setAnimationUpdateInterval(200);
        swimR.setAnimationLoop(false);
        animations.add(swimR);

        Animation swimD = new Animation();
        swimD.addFrame(new Frame(GLSpriteSheet.getInstance(), 32, 32, 160f, 224f, 0, 0));
        swimD.addFrame(new Frame(GLSpriteSheet.getInstance(), 32, 32, 192, 224f, 0, 0));
        swimD.setAnimationUpdateInterval(200);
        swimD.setAnimationLoop(false);
        animations.add(swimD);

        Animation swimU = new Animation();
        swimU.addFrame(new Frame(GLSpriteSheet.getInstance(), 32, 32, 96f, 224f, 0, 0));
        swimU.addFrame(new Frame(GLSpriteSheet.getInstance(), 32, 32, 128, 224f, 0, 0));
        swimU.setAnimationUpdateInterval(200);
        swimU.setAnimationLoop(false);
        animations.add(swimU);

        currentAnim = animations.get(4);
    }

    /**
     * 
     * @param xScroll
     * @param yScroll
     */
    @Override
        public void render(int xScroll, int yScroll) {



        currentAnim.render(x - xScroll, y - yScroll);


    }

    /**
     * 
     * @param xa
     * @param ya
     * @return
     */
    @Override
        public boolean move(int xa, int ya) {
        if (xa != 0 || ya != 0) {
            walkDist++;
        }
        return super.move(xa, ya);
    }

    /**
     * 
     * @param level
     * @return
     */
    public boolean findStartPos(Level level) {
        while (true) {
            int x = random.nextInt(level.w);
            int y = random.nextInt(level.h);
            if (level.getTile(x, y) == TileManager.grass) {
                this.x = x * 32;
                this.y = y * 32;
                return true;
            }
        }
    }

    /**
     * 
     * @return
     */
    public boolean canSwim() {
        return true;
    }

    /**
     * 
     * @return
     */
    protected boolean isSwimming() {

        int position[] = this.getCurrentTile();

        Tile tile = level.getTile(position[0], position[1]);
        return tile == TileManager.water;
    }

    private void attack() {
        int yo = 16;
        int xo = 16;
        int r = 32;
        int xt = x >> 5;
        int yt = (y + r + yo) >> 5;

        if (dir == 'u') {
            xt = (x + xo) >> 5;
            yt = (y + yo - r) >> 5;
        }
        if (dir == 'd') {
            xt = (x + xo) >> 5;
            yt = (y + yo + r) >> 5;
        }
        if (dir == 'l') {
            xt = (x + xo - r) >> 5;
            yt = (y + yo) >> 5;
        }
        if (dir == 'r') {
            xt = (x + xo + r) >> 5;
            yt = (y + yo) >> 5;
        }

        if (xt >= 0 && yt >= 0 && xt < level.w && yt < level.h) {

            level.getTile(xt, yt).hurt(level, xt, yt, this, 10, dir);


        }
    }

    private void place() {
        int yo = 20;
        int xo = 20;
        int r = 20;
        int xt = x >> 5;
        int yt = (y + r + yo) >> 5;

        if (dir == 'u') {
            xt = (x + xo) >> 5;
            yt = (y + yo - r) >> 5;
        }
        if (dir == 'd') {
            xt = (x + xo) >> 5;
            yt = (y + yo + r) >> 5;
        }
        if (dir == 'l') {
            xt = (x + xo - r) >> 5;
            yt = (y + yo) >> 5;
        }
        if (dir == 'r') {
            xt = (x + xo + r) >> 5;
            yt = (y + yo) >> 5;
        }

        if (xt >= 0 && yt >= 0 && xt < level.w && yt < level.h) {
            if (level.getTile(xt, yt) == TileManager.tunnel) {
                level.setTile(xt, yt, TileManager.brick, 0);
                if (dir == 'u') {
                    y += 32;
                }
                if (dir == 'd') {
                    y -= 32;
                }
                if (dir == 'l') {
                    x += 32;
                }
                if (dir == 'r') {
                    x -= 32;
                }
            }

        }
    }

    /**
     * 
     * @return
     */
    @Override
        public int getLightRadius() {
        return 4;
    }

    /**
     * 
     */
    public void stop() {
        stopped = true;
    }

    /**
     * 
     */
    public void start() {
        stopped = false;
    }
}
